package com.dy.design_pattern_study.visitor_pattern.dome3;

import com.dy.design_pattern_study.visitor_pattern.dome3.impl_element.ConcreteElementA;
import com.dy.design_pattern_study.visitor_pattern.dome3.impl_element.ConcreteElementB;
import com.dy.design_pattern_study.visitor_pattern.dome3.impl_visitor.ConcreteVisitor1;
import com.dy.design_pattern_study.visitor_pattern.dome3.impl_visitor.ConcreteVisitor2;
import com.dy.design_pattern_study.visitor_pattern.dome3.tools.ObjectStructure;

/**
 * @CreateBy zhangdingyi
 * @Date 2023-04-25
 * @Content 访问者模式（Visitor），
 * 表示一个作用于某对象结构中的各元素的操作。
 * 它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
 * <p>
 * 简单的说，
 * 这个实质上，就是有访问者、被访问者、工具访问类，被访问者，在工具访问类中登记然后可以被访问者访问
 * 就是在基本的被访问者 固定不变的前提下（数据结构不变），才可以用访问者模式来实现
 * 因此该模式使用范围较少，用得少
 * 可以让同一个类进行，进行不同的动作
 */
public class client {
    /*
        什么地方才能使用访问者模式？
        1.访问者模式适用于数据结构相对稳定的系统

        2.每加一种类别，就需要在状态类和它的所有下属类中都增加一个方法，
        这就不符合开放-封闭原则，因此被访问者一般不能变

        3.访问者模式的目的是要把处理从数据结构分离出来。
        很多系统可以按照算法和数据结构分开，如果这样的系统有比较稳定的数据结构，
        又有易于变化的算法的话，使用访问者模式就是比较合适的，因为访问者模式使得算法操作的增加变得容易。

        4.如果这样的系统的数据结构对象易于变化，经常要有新的数据对象增加进来，就不适合使用访问者模式
     */
    /*
        访问者模式的优缺点
        优点
        1.完美的体现了开放-封闭原则，新增开放、关闭修改
        2.访问者模式把数据结构和作用于结构上的操作之间的耦合解脱开，使得操作集合可以相对自由地演化。
        3.访问者模式的优点就是 增加新的操作很容易 ，因为增加新的操作就意味着增加一个新的访问者。
        访问者模式将有关的行为集中到一个访问者对象中

        缺点
        1.每加一种类别，就需要在状态类和它的所有下属类中都增加一个方法，
        这就不符合开放-封闭原则，因此被访问者一般不能变
        2.访问者模式使增加新的数据结构变得困难了
        3.我们很难找到数据结构不变化的情况，所以用访问者模式的机会也就不太多了
     */

    public static void main(String[] args) {
        ObjectStructure o = new ObjectStructure();
        o.attach(new ConcreteElementA());
        o.attach(new ConcreteElementB());

        //设置被访问者
        ConcreteVisitor1 v1 = new ConcreteVisitor1();
        ConcreteVisitor2 v2 = new ConcreteVisitor2();
        o.accept(v1);
        o.accept(v2);
    }
}
